home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / FLEX-TC_ / GEN.C < prev    next >
Text File  |  1990-01-03  |  24KB  |  1,095 lines

  1. /* gen - actual generation (writing) of flex scanners */
  2.  
  3. /*
  4.  * Copyright (c) 1989 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  *
  10.  * The United States Government has rights in this work pursuant to
  11.  * contract no. DE-AC03-76SF00098 between the United States Department of
  12.  * Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted
  15.  * provided that the above copyright notice and this paragraph are
  16.  * duplicated in all such forms and that any documentation,
  17.  * advertising materials, and other materials related to such
  18.  * distribution and use acknowledge that the software was developed
  19.  * by the University of California, Berkeley.  The name of the
  20.  * University may not be used to endorse or promote products derived
  21.  * from this software without specific prior written permission.
  22.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  23.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  24.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25.  */
  26.  
  27. #ifndef lint
  28.  
  29. static char copyright[] =
  30. "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
  31. static char CR_continuation[] = "@(#) All rights reserved.\n";
  32.  
  33. static char rcsid[] =
  34. "@(#) $Header: gen.c,v 2.0 89/06/20 15:49:54 vern Locked $ (LBL)";
  35.  
  36. #endif
  37.  
  38. #include "flexdef.h"
  39.  
  40.  
  41. static int indent_level = 0; /* each level is 4 spaces */
  42.  
  43. #define indent_up() (++indent_level)
  44. #define indent_down() (--indent_level)
  45. #define set_indent(indent_val) indent_level = indent_val
  46.  
  47.  
  48.  
  49. /* indent to the current level */
  50.  
  51. do_indent()
  52.  
  53. {
  54.     register int i = indent_level * 4;
  55.  
  56.     while ( i >= 8 )
  57.     {
  58.         putchar( '\t' );
  59.         i -= 8;
  60.     }
  61.  
  62.     while ( i > 0 )
  63.     {
  64.         putchar( ' ' );
  65.         --i;
  66.     }
  67. }
  68.  
  69.  
  70. /* generate the code to keep backtracking information */
  71.  
  72. gen_backtracking()
  73.  
  74. {
  75.     if ( reject || num_backtracking == 0 )
  76.         return;
  77.  
  78.     if ( fullspd )
  79.         indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
  80.     else
  81.         indent_puts( "if ( yy_accept[yy_current_state] )" );
  82.  
  83.     indent_up();
  84.     indent_puts( "{" );
  85.     indent_puts( "yy_last_accepting_state = yy_current_state;" );
  86.     indent_puts( "yy_last_accepting_cpos = yy_cp;" );
  87.     indent_puts( "}" );
  88.     indent_down();
  89. }
  90.  
  91.  
  92. /* generate the code to perform the backtrack */
  93.  
  94. gen_bt_action()
  95.  
  96. {
  97.     if ( reject || num_backtracking == 0 )
  98.         return;
  99.  
  100.     set_indent( 4 );
  101.  
  102.     indent_puts( "case 0: /* must backtrack */" );
  103.     indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
  104.     indent_puts( "*yy_cp = yy_hold_char;" );
  105.  
  106.     if ( fullspd || fulltbl )
  107.         indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
  108.     else     /* backtracking info for compressed tables is taken \after/
  109.      * yy_cp has been incremented for the next state
  110.      */
  111.         indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  112.  
  113.     indent_puts( "yy_current_state = yy_last_accepting_state;" );
  114.     indent_puts( "continue; /* go to \"YY_DO_BEFORE_ACTION\" */" );
  115.     putchar( '\n' );
  116.  
  117.     set_indent( 0 );
  118. }
  119.  
  120.  
  121. /* genctbl - generates full speed compressed transition table
  122.  *
  123.  * synopsis
  124.  *       genctbl();
  125.  */
  126.  
  127. genctbl()
  128.  
  129. {
  130.     register int i;
  131.     int end_of_buffer_action = num_rules + 1;
  132.  
  133.     /* table of verify for transition and offset to next state */
  134.     printf( "static const struct yy_trans_info yy_transition[%d] =\n",
  135.     tblend + numecs + 1 );
  136.     printf( "    {\n" );
  137.  
  138.     /* We want the transition to be represented as the offset to the
  139.      * next state, not the actual state number, which is what it currently is.
  140.      * The offset is base[nxt[i]] - base[chk[i]].  That's just the
  141.      * difference between the starting points of the two involved states
  142.      * (to - from).
  143.      *
  144.      * first, though, we need to find some way to put in our end-of-buffer
  145.      * flags and states.  We do this by making a state with absolutely no
  146.      * transitions.  We put it at the end of the table.
  147.      */
  148.     /* at this point, we're guaranteed that there's enough room in nxt[]
  149.      * and chk[] to hold tblend + numecs entries.  We need just two slots.
  150.      * One for the action and one for the end-of-buffer transition.  We
  151.      * now *assume* that we're guaranteed the only character we'll try to
  152.      * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to
  153.      * make sure there's room for jam entries for other characters.
  154.      */
  155.  
  156.     base[lastdfa + 1] = tblend + 2;
  157.     nxt[tblend + 1] = end_of_buffer_action;
  158.     chk[tblend + 1] = numecs + 1;
  159.     chk[tblend + 2] = 1; /* anything but EOB */
  160.     nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */
  161.  
  162.     /* make sure every state has a end-of-buffer transition and an action # */
  163.     for ( i = 0; i <= lastdfa; ++i )
  164.     {
  165.         register int anum = dfaacc[i].dfaacc_state;
  166.  
  167.         chk[base[i]] = EOB_POSITION;
  168.         chk[base[i] - 1] = ACTION_POSITION;
  169.         nxt[base[i] - 1] = anum;    /* action number */
  170.     }
  171.  
  172.     dataline = 0;
  173.     datapos = 0;
  174.  
  175.     for ( i = 0; i <= tblend; ++i )
  176.     {
  177.         if ( chk[i] == EOB_POSITION )
  178.             transition_struct_out( 0, base[lastdfa + 1] - i );
  179.  
  180.         else
  181.             if ( chk[i] == ACTION_POSITION )
  182.                 transition_struct_out( 0, nxt[i] );
  183.  
  184.         else
  185.             if ( chk[i] > numecs || chk[i] == 0 )
  186.                 transition_struct_out( 0, 0 );        /* unused slot */
  187.  
  188.         else    /* verify, transition */
  189.             transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) );
  190.     }
  191.  
  192.  
  193.     /* here's the final, end-of-buffer state */
  194.     transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
  195.     transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
  196.  
  197.     printf( "    };\n" );
  198.     printf( "\n" );
  199.  
  200.     /* table of pointers to start states */
  201.     printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
  202.     lastsc * 2 + 1 );
  203.     printf( "    {\n" );
  204.  
  205.     for ( i = 0; i <= lastsc * 2; ++i )
  206.         printf( "    &yy_transition[%d],\n", base[i] );
  207.  
  208.     printf( "    };\n" );
  209.  
  210.     if ( useecs )
  211.         genecs();
  212. }
  213.  
  214.  
  215. /* generate equivalence-class tables */
  216.  
  217. genecs()
  218.  
  219. {
  220.     register int i, j;
  221.     static char C_char_decl[] = "static const char %s[%d] =\n    {   0,\n";
  222.     int numrows;
  223.     char clower();
  224.  
  225.     printf( C_char_decl, ECARRAY, CSIZE + 1 );
  226.  
  227.     for ( i = 1; i <= CSIZE; ++i )
  228.     {
  229.         if ( caseins && (i >= 'A') && (i <= 'Z') )
  230.             ecgroup[i] = ecgroup[clower( i )];
  231.  
  232.         ecgroup[i] = abs( ecgroup[i] );
  233.         mkdata( ecgroup[i] );
  234.     }
  235.  
  236.     dataend();
  237.  
  238.     if ( trace )
  239.     {
  240.         fputs( "\n\nEquivalence Classes:\n\n", stderr );
  241.  
  242.         numrows = (CSIZE + 1) / 8;
  243.  
  244.         for ( j = 1; j <= numrows; ++j )
  245.         {
  246.             for ( i = j; i <= CSIZE; i = i + numrows )
  247.             {
  248.                 char *readable_form();
  249.  
  250.                 fprintf( stderr, "%4s = %-2d",
  251.                 readable_form( i ), ecgroup[i] );
  252.  
  253.                 putc( ' ', stderr );
  254.             }
  255.  
  256.             putc( '\n', stderr );
  257.         }
  258.     }
  259. }
  260.  
  261.  
  262. /* generate the code to find the action number */
  263.  
  264. gen_find_action()
  265.  
  266. {
  267.     if ( fullspd )
  268.         indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" );
  269.  
  270.     else
  271.         if ( fulltbl )
  272.             indent_puts( "yy_act = yy_accept[yy_current_state];" );
  273.  
  274.     else
  275.         if ( reject )
  276.         {
  277.             indent_puts( "yy_current_state = *--yy_state_ptr;" );
  278.             indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  279.  
  280.             puts( "find_rule: /* we branch to this label when backtracking */" );
  281.  
  282.             indent_puts( "for ( ; ; ) /* until we find what rule we matched */" );
  283.  
  284.             indent_up();
  285.  
  286.             indent_puts( "{" );
  287.  
  288.             indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
  289.             indent_up();
  290.             indent_puts( "{" );
  291.             indent_puts( "yy_act = yy_acclist[yy_lp];" );
  292.  
  293.             if ( variable_trailing_context_rules )
  294.             {
  295.                 indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
  296.                 indent_puts( "     yy_looking_for_trail_begin )" );
  297.                 indent_up();
  298.                 indent_puts( "{" );
  299.  
  300.                 indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" );
  301.                 indent_up();
  302.                 indent_puts( "{" );
  303.                 indent_puts( "yy_looking_for_trail_begin = 0;" );
  304.                 indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );
  305.                 indent_puts( "break;" );
  306.                 indent_puts( "}" );
  307.                 indent_down();
  308.  
  309.                 indent_puts( "}" );
  310.                 indent_down();
  311.  
  312.                 indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );
  313.                 indent_up();
  314.                 indent_puts( "{" );
  315.                 indent_puts(
  316.                 "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );
  317.                 indent_puts(
  318.                 "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );
  319.  
  320.                 if ( real_reject )
  321.                 {
  322.                     /* remember matched text in case we back up due to REJECT */
  323.                     indent_puts( "yy_full_match = yy_cp;" );
  324.                     indent_puts( "yy_full_state = yy_state_ptr;" );
  325.                     indent_puts( "yy_full_lp = yy_lp;" );
  326.                 }
  327.  
  328.                 indent_puts( "}" );
  329.                 indent_down();
  330.  
  331.                 indent_puts( "else" );
  332.                 indent_up();
  333.                 indent_puts( "{" );
  334.                 indent_puts( "yy_full_match = yy_cp;" );
  335.                 indent_puts( "yy_full_state = yy_state_ptr;" );
  336.                 indent_puts( "yy_full_lp = yy_lp;" );
  337.                 indent_puts( "break;" );
  338.                 indent_puts( "}" );
  339.                 indent_down();
  340.  
  341.                 indent_puts( "++yy_lp;" );
  342.                 indent_puts( "goto find_rule;" );
  343.             }
  344.  
  345.             else
  346.             {
  347.                 /* remember matched text in case we back up due to trailing context
  348.                  * plus REJECT
  349.                  */
  350.                 indent_up();
  351.                 indent_puts( "{" );
  352.                 indent_puts( "yy_full_match = yy_cp;" );
  353.                 indent_puts( "break;" );
  354.                 indent_puts( "}" );
  355.                 indent_down();
  356.             }
  357.  
  358.             indent_puts( "}" );
  359.             indent_down();
  360.  
  361.             indent_puts( "--yy_cp;" );
  362.  
  363.             /* we could consolidate the following two lines with those at
  364.              * the beginning, but at the cost of complaints that we're
  365.              * branching inside a loop
  366.              */
  367.             indent_puts( "yy_current_state = *--yy_state_ptr;" );
  368.             indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  369.  
  370.             indent_puts( "}" );
  371.  
  372.             indent_down();
  373.         }
  374.  
  375.     else     /* compressed */
  376.         indent_puts( "yy_act = yy_accept[yy_current_state];" );
  377. }
  378.  
  379.  
  380. /* genftbl - generates full transition table
  381.  *
  382.  * synopsis
  383.  *       genftbl();
  384.  */
  385.  
  386. genftbl()
  387.  
  388. {
  389.     register int i;
  390.     int end_of_buffer_action = num_rules + 1;
  391.  
  392.     /* *everything* is done in terms of arrays starting at 1, so provide
  393.      * a null entry for the zero element of all C arrays
  394.      */
  395.     static char C_short_decl[] =
  396.         "static const short int %s[%d] =\n    {   0,\n";
  397.  
  398.     printf( C_short_decl, ALIST, lastdfa + 1 );
  399.  
  400.  
  401.     dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  402.  
  403.     for ( i = 1; i <= lastdfa; ++i )
  404.     {
  405.         register int anum = dfaacc[i].dfaacc_state;
  406.  
  407.         mkdata( anum );
  408.  
  409.         if ( trace && anum )
  410.             fprintf( stderr, "state # %d accepts: [%d]\n", i, anum );
  411.     }
  412.  
  413.     dataend();
  414.  
  415.     if ( useecs )
  416.         genecs();
  417.  
  418.     /* don't have to dump the actual full table entries - they were created
  419.      * on-the-fly
  420.      */
  421. }
  422.  
  423.  
  424. /* generate the code to find the next compressed-table state */
  425.  
  426. gen_next_compressed_state()
  427.  
  428. {
  429.     char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  430.  
  431.     indent_put2s( "register char yy_c = %s;", char_map );
  432.  
  433.     /* save the backtracking info \before/ computing the next state
  434.      * because we always compute one more state than needed - we
  435.      * always proceed until we reach a jam state
  436.      */
  437.     gen_backtracking();
  438.  
  439.     indent_puts(
  440.     "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );
  441.     indent_up();
  442.     indent_puts( "{" );
  443.     indent_puts( "yy_current_state = yy_def[yy_current_state];" );
  444.  
  445.     if ( usemecs )
  446.     {
  447.         /* we've arrange it so that templates are never chained
  448.          * to one another.    This means we can afford make a
  449.          * very simple test to see if we need to convert to
  450.          * yy_c's meta-equivalence class without worrying
  451.          * about erroneously looking up the meta-equivalence
  452.          * class twice
  453.          */
  454.         do_indent();
  455.         /* lastdfa + 2 is the beginning of the templates */
  456.         printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
  457.  
  458.         indent_up();
  459.         indent_puts( "yy_c = yy_meta[yy_c];" );
  460.         indent_down();
  461.     }
  462.  
  463.     indent_puts( "}" );
  464.     indent_down();
  465.  
  466.     indent_puts(
  467.     "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" );
  468. }
  469.  
  470.  
  471. /* generate the code to find the next match */
  472.  
  473. gen_next_match()
  474.  
  475. { /* NOTE - changes in here should be reflected in get_next_state() */
  476.     char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  477.     char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp";
  478.  
  479.     if ( fulltbl )
  480.     {
  481.         indent_put2s(
  482.         "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
  483.         char_map );
  484.  
  485.         indent_up();
  486.  
  487.         if ( num_backtracking > 0 )
  488.         {
  489.             indent_puts( "{" );
  490.             gen_backtracking();
  491.             putchar( '\n' );
  492.         }
  493.  
  494.         indent_puts( "++yy_cp;" );
  495.  
  496.         if ( num_backtracking > 0 )
  497.             indent_puts( "}" );
  498.  
  499.         indent_down();
  500.  
  501.         putchar( '\n' );
  502.         indent_puts( "yy_current_state = -yy_current_state;" );
  503.     }
  504.  
  505.     else
  506.         if ( fullspd )
  507.         {
  508.             indent_puts( "{" );
  509.             indent_puts( "register struct yy_trans_info *yy_trans_info;\n" );
  510.             indent_puts( "register char yy_c;\n" );
  511.             indent_put2s( "for ( yy_c = %s;", char_map );
  512.             indent_puts(
  513.             "      (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" );
  514.             indent_put2s( "      yy_c = %s )", char_map_2 );
  515.  
  516.             indent_up();
  517.  
  518.             if ( num_backtracking > 0 )
  519.                 indent_puts( "{" );
  520.  
  521.             indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
  522.  
  523.             if ( num_backtracking > 0 )
  524.             {
  525.                 putchar( '\n' );
  526.                 gen_backtracking();
  527.                 indent_puts( "}" );
  528.             }
  529.  
  530.             indent_down();
  531.             indent_puts( "}" );
  532.         }
  533.  
  534.     else
  535.     { /* compressed */
  536.         indent_puts( "do" );
  537.  
  538.         indent_up();
  539.         indent_puts( "{" );
  540.  
  541.         gen_next_state();
  542.  
  543.         indent_puts( "++yy_cp;" );
  544.  
  545.         indent_puts( "}" );
  546.         indent_down();
  547.  
  548.         do_indent();
  549.  
  550.         if ( interactive )
  551.             printf( "while ( yy_base[yy_current_state] != %d );\n", jambase );
  552.         else
  553.             printf( "while ( yy_current_state != %d );\n", jamstate );
  554.  
  555.         if ( ! reject && ! interactive )
  556.         {
  557.             /* do the guaranteed-needed backtrack to figure out the match */
  558.             indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  559.             indent_puts( "yy_current_state = yy_last_accepting_state;" );
  560.         }
  561.     }
  562. }
  563.  
  564.  
  565. /* generate the code to find the next state */
  566.  
  567. gen_next_state()
  568.  
  569. { /* NOTE - changes in here should be reflected in get_next_match() */
  570.     char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  571.  
  572.     if ( fulltbl )
  573.     {
  574.         indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];",
  575.         char_map );
  576.         gen_backtracking();
  577.     }
  578.  
  579.     else
  580.         if ( fullspd )
  581.         {
  582.             indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;",
  583.             char_map );
  584.             gen_backtracking();
  585.         }
  586.  
  587.     else
  588.     {
  589.         gen_next_compressed_state();
  590.  
  591.         if ( reject )
  592.             indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  593.     }
  594. }
  595.  
  596.  
  597. /* generate the code to find the start state */
  598.  
  599. gen_start_state()
  600.  
  601. {
  602.     if ( fullspd )
  603.         indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];",
  604.         bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" );
  605.  
  606.     else
  607.     {
  608.         indent_puts( "yy_current_state = yy_start;" );
  609.  
  610.         if ( bol_needed )
  611.         {
  612.             indent_puts( "if ( yy_bp[-1] == '\\n' )" );
  613.             indent_up();
  614.             indent_puts( "++yy_current_state;" );
  615.             indent_down();
  616.         }
  617.  
  618.         if ( reject )
  619.         {
  620.             /* set up for storing up states */
  621.             indent_puts( "yy_state_ptr = yy_state_buf;" );
  622.             indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  623.         }
  624.     }
  625. }
  626.  
  627.  
  628. /* gentabs - generate data statements for the transition tables
  629.  *
  630.  * synopsis
  631.  *      gentabs();
  632.  */
  633.  
  634. gentabs()
  635.  
  636. {
  637.     int i, j, k, *accset, nacc, *acc_array, total_states;
  638.     int end_of_buffer_action = num_rules + 1;
  639.  
  640.     /* *everything* is done in terms of arrays starting at 1, so provide
  641.      * a null entry for the zero element of all C arrays
  642.      */
  643.     static char C_long_decl[] =
  644.         "static const long int %s[%d] =\n    {   0,\n";
  645.     static char C_short_decl[] =
  646.         "static const short int %s[%d] =\n    {   0,\n";
  647.     static char C_char_decl[] =
  648.         "static const char %s[%d] =\n    {   0,\n";
  649.  
  650.     acc_array = allocate_integer_array( current_max_dfas );
  651.     nummt = 0;
  652.  
  653.     /* the compressed table format jams by entering the "jam state",
  654.      * losing information about the previous state in the process.
  655.      * In order to recover the previous state, we effectively need
  656.      * to keep backtracking information.
  657.      */
  658.     ++num_backtracking;
  659.  
  660.     if ( reject )
  661.     {
  662.         /* write out accepting list and pointer list
  663.          *
  664.          * first we generate the ACCEPT array.    In the process, we compute
  665.          * the indices that will go into the ALIST array, and save the
  666.          * indices in the dfaacc array
  667.          */
  668.         int EOB_accepting_list[2];
  669.  
  670.         printf( C_short_decl, ACCEPT, max( numas, 1 ) + 1 );
  671.  
  672.         /* set up accepting structures for the End Of Buffer state */
  673.         EOB_accepting_list[0] = 0;
  674.         EOB_accepting_list[1] = end_of_buffer_action;
  675.         accsiz[end_of_buffer_state] = 1;
  676.         dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
  677.  
  678.         j = 1;    /* index into ACCEPT array */
  679.  
  680.         for ( i = 1; i <= lastdfa; ++i )
  681.         {
  682.             acc_array[i] = j;
  683.  
  684.             if ( accsiz[i] != 0 )
  685.             {
  686.                 accset = dfaacc[i].dfaacc_set;
  687.                 nacc = accsiz[i];
  688.  
  689.                 if ( trace )
  690.                     fprintf( stderr, "state # %d accepts: ", i );
  691.  
  692.                 for ( k = 1; k <= nacc; ++k )
  693.                 {
  694.                     int accnum = accset[k];
  695.  
  696.                     ++j;
  697.  
  698.                     if ( variable_trailing_context_rules &&
  699.                         ! (accnum & YY_TRAILING_HEAD_MASK) &&
  700.                         accnum > 0 &&
  701.                         rule_type[accnum] == RULE_VARIABLE )
  702.                     {
  703.                         /* special hack to flag accepting number as part
  704.                          * of trailing context rule
  705.                          */
  706.                         accnum |= YY_TRAILING_MASK;
  707.                     }
  708.  
  709.                     mkdata( accnum );
  710.  
  711.                     if ( trace )
  712.                     {
  713.                         fprintf( stderr, "[%d]", accset[k] );
  714.  
  715.                         if ( k < nacc )
  716.                             fputs( ", ", stderr );
  717.                         else
  718.                             putc( '\n', stderr );
  719.                     }
  720.                 }
  721.             }
  722.         }
  723.  
  724.         /* add accepting number for the "jam" state */
  725.         acc_array[i] = j;
  726.  
  727.         dataend();
  728.     }
  729.  
  730.     else
  731.     {
  732.         dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  733.  
  734.         for ( i = 1; i <= lastdfa; ++i )
  735.             acc_array[i] = dfaacc[i].dfaacc_state;
  736.  
  737.         /* add accepting number for jam state */
  738.         acc_array[i] = 0;
  739.     }
  740.  
  741.     /* spit out ALIST array.  If we're doing "reject", it'll be pointers
  742.      * into the ACCEPT array.  Otherwise it's actual accepting numbers.
  743.      * In either case, we just dump the numbers.
  744.      */
  745.  
  746.     /* "lastdfa + 2" is the size of ALIST; includes room for C arrays
  747.      * beginning at 0 and for "jam" state
  748.      */
  749.     k = lastdfa + 2;
  750.  
  751.     if ( reject )     /* we put a "cap" on the table associating lists of accepting
  752.      * numbers with state numbers.    This is needed because we tell
  753.      * where the end of an accepting list is by looking at where
  754.      * the list for the next state starts.
  755.      */
  756.         ++k;
  757.  
  758.     printf( C_short_decl, ALIST, k );
  759.  
  760.     for ( i = 1; i <= lastdfa; ++i )
  761.     {
  762.         mkdata( acc_array[i] );
  763.  
  764.         if ( ! reject && trace && acc_array[i] )
  765.             fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] );
  766.     }
  767.  
  768.     /* add entry for "jam" state */
  769.     mkdata( acc_array[i] );
  770.  
  771.     if ( reject )     /* add "cap" for the list */
  772.         mkdata( acc_array[i] );
  773.  
  774.     dataend();
  775.  
  776.     if ( useecs )
  777.         genecs();
  778.  
  779.     if ( usemecs )
  780.     {
  781.         /* write out meta-equivalence classes (used to index templates with) */
  782.  
  783.         if ( trace )
  784.             fputs( "\n\nMeta-Equivalence Classes:\n", stderr );
  785.  
  786.         printf( C_char_decl, MATCHARRAY, numecs + 1 );
  787.  
  788.         for ( i = 1; i <= numecs; ++i )
  789.         {
  790.             if ( trace )
  791.                 fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) );
  792.  
  793.             mkdata( abs( tecbck[i] ) );
  794.         }
  795.  
  796.         dataend();
  797.     }
  798.  
  799.     total_states = lastdfa + numtemps;
  800.  
  801.     printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  802.     BASEARRAY, total_states + 1 );
  803.  
  804.     for ( i = 1; i <= lastdfa; ++i )
  805.     {
  806.         register int d = def[i];
  807.  
  808.         if ( base[i] == JAMSTATE )
  809.             base[i] = jambase;
  810.  
  811.         if ( d == JAMSTATE )
  812.             def[i] = jamstate;
  813.  
  814.         else
  815.             if ( d < 0 )
  816.             {
  817.                 /* template reference */
  818.                 ++tmpuses;
  819.                 def[i] = lastdfa - d + 1;
  820.             }
  821.  
  822.         mkdata( base[i] );
  823.     }
  824.  
  825.     /* generate jam state's base index */
  826.     mkdata( base[i] );
  827.  
  828.     for ( ++i /* skip jam state */; i <= total_states; ++i )
  829.     {
  830.         mkdata( base[i] );
  831.         def[i] = jamstate;
  832.     }
  833.  
  834.     dataend();
  835.  
  836.     printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  837.     DEFARRAY, total_states + 1 );
  838.  
  839.     for ( i = 1; i <= total_states; ++i )
  840.         mkdata( def[i] );
  841.  
  842.     dataend();
  843.  
  844.     printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  845.     NEXTARRAY, tblend + 1 );
  846.  
  847.     for ( i = 1; i <= tblend; ++i )
  848.     {
  849.         if ( nxt[i] == 0 || chk[i] == 0 )
  850.             nxt[i] = jamstate;    /* new state is the JAM state */
  851.  
  852.         mkdata( nxt[i] );
  853.     }
  854.  
  855.     dataend();
  856.  
  857.     printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  858.     CHECKARRAY, tblend + 1 );
  859.  
  860.     for ( i = 1; i <= tblend; ++i )
  861.     {
  862.         if ( chk[i] == 0 )
  863.             ++nummt;
  864.  
  865.         mkdata( chk[i] );
  866.     }
  867.  
  868.     dataend();
  869. }
  870.  
  871.  
  872. /* write out a formatted string (with a secondary string argument) at the
  873.  * current indentation level, adding a final newline
  874.  */
  875.  
  876. indent_put2s( fmt, arg )
  877. char fmt[], arg[];
  878.  
  879. {
  880.     do_indent();
  881.     printf( fmt, arg );
  882.     putchar( '\n' );
  883. }
  884.  
  885.  
  886. /* write out a string at the current indentation level, adding a final
  887.  * newline
  888.  */
  889.  
  890. indent_puts( str )
  891. char str[];
  892.  
  893. {
  894.     do_indent();
  895.     puts( str );
  896. }
  897.  
  898.  
  899. /* make_tables - generate transition tables
  900.  *
  901.  * synopsis
  902.  *       make_tables();
  903.  *
  904.  * Generates transition tables and finishes generating output file
  905.  */
  906.  
  907. make_tables()
  908.  
  909. {
  910.     register int i;
  911.     int did_eof_rule = false;
  912.  
  913.     printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
  914.  
  915.     if ( fullspd )
  916.     { /* need to define the transet type as a size large
  917.      * enough to hold the biggest offset
  918.      */
  919.         int total_table_size = tblend + numecs + 1;
  920.         char *trans_offset_type =
  921.             total_table_size > MAX_SHORT ? "long" : "short";
  922.  
  923.         set_indent( 0 );
  924.         indent_puts( "struct yy_trans_info" );
  925.         indent_up();
  926.         indent_puts( "{" );
  927.         indent_puts( "short yy_verify;" );
  928.  
  929.         /* in cases where its sister yy_verify *is* a "yes, there is a
  930.          * transition", yy_nxt is the offset (in records) to the next state.
  931.          * In most cases where there is no transition, the value of yy_nxt
  932.          * is irrelevant.  If yy_nxt is the -1th  record of a state, though,
  933.          * then yy_nxt is the action number for that state
  934.          */
  935.  
  936.         indent_put2s( "%s yy_nxt;", trans_offset_type );
  937.         indent_puts( "};" );
  938.         indent_down();
  939.  
  940.         indent_puts( "typedef struct yy_trans_info *yy_state_type;" );
  941.     }
  942.  
  943.     else
  944.         indent_puts( "typedef int yy_state_type;" );
  945.  
  946.     if ( fullspd )
  947.         genctbl();
  948.  
  949.     else
  950.         if ( fulltbl )
  951.             genftbl();
  952.  
  953.     else
  954.         gentabs();
  955.  
  956.     if ( reject )
  957.     {
  958.         /* declare state buffer variables */
  959.         puts( "yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
  960.         puts( "char *yy_full_match;" );
  961.         puts( "int yy_lp;" );
  962.  
  963.         if ( variable_trailing_context_rules )
  964.         {
  965.             puts( "int yy_looking_for_trail_begin = 0;" );
  966.             puts( "int yy_full_lp;" );
  967.             puts( "int *yy_full_state;" );
  968.             printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK );
  969.             printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
  970.             YY_TRAILING_HEAD_MASK );
  971.         }
  972.  
  973.         puts( "#define REJECT \\" );
  974.         puts( "{ \\" );
  975.         puts(
  976.         "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
  977.         puts(
  978.         "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
  979.  
  980.         if ( variable_trailing_context_rules )
  981.         {
  982.             puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
  983.             puts(
  984.             "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
  985.             puts(
  986.             "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
  987.         }
  988.  
  989.         puts( "++yy_lp; \\" );
  990.         puts( "goto find_rule; \\" );
  991.         puts( "}" );
  992.     }
  993.  
  994.     else
  995.     {
  996.         puts( "/* the intent behind this definition is that it'll catch" );
  997.         puts( " * any uses of REJECT which flex missed" );
  998.         puts( " */" );
  999.         puts( "#define REJECT reject_used_but_not_detected" );
  1000.     }
  1001.  
  1002.     if ( yymore_used )
  1003.     {
  1004.         indent_puts( "static char *yy_more_pos = (char *) 0;" );
  1005.         indent_puts( "#define yymore() (yy_more_pos = yy_bp)" );
  1006.     }
  1007.  
  1008.     else
  1009.         indent_puts( "#define yymore() yymore_used_but_not_detected" );
  1010.  
  1011.  
  1012.     skelout();
  1013.  
  1014.     (void) fclose( temp_action_file );
  1015.     temp_action_file = fopen( action_file_name, "r" );
  1016.  
  1017.     /* copy prolog from action_file to output file */
  1018.     action_out();
  1019.  
  1020.     skelout();
  1021.  
  1022.     set_indent( 2 );
  1023.  
  1024.     if ( yymore_used )
  1025.     {
  1026.         indent_puts( "if ( yy_more_pos )" );
  1027.         indent_up();
  1028.         indent_puts( "{" );
  1029.         indent_puts( "yy_bp = yy_more_pos;" );
  1030.         indent_puts( "yy_more_pos = (char *) 0;" );
  1031.         indent_puts( "}" );
  1032.         indent_down();
  1033.         indent_puts( "else" );
  1034.         indent_up();
  1035.         indent_puts( "yy_bp = yy_cp;" );
  1036.         indent_down();
  1037.     }
  1038.  
  1039.     else
  1040.         indent_puts( "yy_bp = yy_cp;" );
  1041.  
  1042.     skelout();
  1043.  
  1044.     gen_start_state();
  1045.     gen_next_match();
  1046.  
  1047.     skelout();
  1048.     set_indent( 3 );
  1049.     gen_find_action();
  1050.  
  1051.     /* copy actions from action_file to output file */
  1052.     skelout();
  1053.     indent_up();
  1054.     gen_bt_action();
  1055.     action_out();
  1056.  
  1057.     /* generate cases for any missing EOF rules */
  1058.     for ( i = 1; i <= lastsc; ++i )
  1059.         if ( ! sceof[i] )
  1060.         {
  1061.             do_indent();
  1062.             printf( "case YY_STATE_EOF(%s):\n", scname[i] );
  1063.             did_eof_rule = true;
  1064.         }
  1065.  
  1066.     if ( did_eof_rule )
  1067.     {
  1068.         indent_up();
  1069.         indent_puts( "yyterminate();" );
  1070.         indent_down();
  1071.     }
  1072.  
  1073.  
  1074.     /* generate code for yy_get_previous_state() */
  1075.     set_indent( 1 );
  1076.     skelout();
  1077.  
  1078.     if ( bol_needed )
  1079.         indent_puts( "register char *yy_bp = yytext;\n" );
  1080.  
  1081.     gen_start_state();
  1082.  
  1083.     set_indent( 2 );
  1084.     skelout();
  1085.     gen_next_state();
  1086.  
  1087.     skelout();
  1088.  
  1089.     /* copy remainder of input to output */
  1090.  
  1091.     line_directive_out( stdout );
  1092.     (void) flexscan(); /* copy remainder of input to output */
  1093. }
  1094.  
  1095.